﻿using Sunboxsoft.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Sunboxsoft.ASMS.Server.Domain.Service
{
    /// <summary>
    /// 结算服务
    /// </summary>
    public class CheckOutService
    {
        /// <summary>
        /// 
        /// 收银-套餐购买单
        /// </summary>
        /// <param name="billId"></param>
        /// <param name="checkOutData"></param>
        /// <param name="payRecordArray"></param>
        /// <returns></returns>
        public ServiceResult CheckOutPackagePurchaseBill(Guid billId, Data.CheckOutData checkOutData, Entity.EPayRecord[] payRecordArray)
        {
            using (ASMSDbContext dbContext = new ASMSDbContext())
            {
                DateTime now = DateTime.Now;

                Entity.EPackagePurchaseBill bill = dbContext.Set<Entity.EPackagePurchaseBill>().SingleOrDefault(p => p.Id == billId && p.Status == Constant.PackagePurchaseBillStatus.Enabled);

                if (bill == null)
                {
                    return new ServiceResult(1, "bill is not exist!");
                }

                List<Entity.EPackageItem> packageItemList = dbContext.Set<Entity.EPackageItem>().Where(p => p.PackageId == bill.PackageId).ToList();

                // 实际支付金额
                decimal payAmount = 0;
                for (int index = 0; index < payRecordArray.Length; index++)
                {
                    payRecordArray[index].Id = Guid.NewGuid();
                    payRecordArray[index].BillId = billId;
                    payRecordArray[index].BillType = Constant.BillTypes.PackagePurchaseBill;
                    payRecordArray[index].CreatedTime = now;
                    payRecordArray[index].Creator = Sunboxsoft.ASMS.WebUtility.CookieUtility.GetUserIdString();
                    payRecordArray[index].SortIndex = index;
                    payAmount += payRecordArray[index].PayAmount;
                    dbContext.Set<Entity.EPayRecord>().Add(payRecordArray[index]);
                }

                bill.PaidAmount = payAmount;
                bill.PaidTime = now;
                if (checkOutData != null && string.IsNullOrEmpty(checkOutData.InvoiceType) == false)
                {
                    bill.InvoiceType = checkOutData.InvoiceType;
                    bill.InvoiceNumber = checkOutData.InvoiceNumber;
                }
                bill.Status = Constant.PackagePurchaseBillStatus.Finished;
                bill.Cashier = Sunboxsoft.ASMS.WebUtility.CookieUtility.GetUserIdString();
                dbContext.Entry<Entity.EPackagePurchaseBill>(bill).State = System.Data.Entity.EntityState.Modified;

                // 创建套餐实例
                Entity.EPackageInstance instance = new Entity.EPackageInstance();
                instance.Id = Guid.NewGuid();
                instance.PackageId = bill.PackageId;
                instance.BusinessId = bill.BusinessId;
                instance.StationId = bill.StationId;
                instance.PackagePurchaseBillId = bill.Id;
                instance.CustomerId = bill.CustomerId;
                instance.Status = Constant.CommonStatus.Enabled;
                instance.CreatedTime = now;
                instance.Creator = Sunboxsoft.ASMS.WebUtility.CookieUtility.GetUserIdString();
                dbContext.Set<Entity.EPackageInstance>().Add(instance);

                // 创建实例项目
                for (int index = 0; index < packageItemList.Count; index++)
                {
                    Entity.EPackageInstanceItem instanceItem = new Entity.EPackageInstanceItem();
                    instanceItem.Id = Guid.NewGuid();
                    instanceItem.PackageInstanceId = instance.Id;
                    instanceItem.PackageItemId = packageItemList[index].Id;
                    instanceItem.Value = packageItemList[index].Value;
                    instanceItem.Status = Constant.CommonStatus.Enabled;
                    dbContext.Set<Entity.EPackageInstanceItem>().Add(instanceItem);
                }

                #region 创建资金入账记录
                InlineCreateService.CreateCapitalIncreaseRecord(dbContext, now, WebUtility.CookieUtility.GetUserIdString(),
                    bill.BusinessId.Value,
                    bill.StationId.Value,
                    Constant.CapitalChangedType.IncreaseCheckoutPackagePurchaseBill,
                    Constant.CapitalRoleTypes.Customer,
                    bill.CustomerId.ToString(),
                    payAmount,
                    bill.Id,
                    Constant.BillTypes.PackagePurchaseBill,
                    bill.Number);
                #endregion

                try
                {
                    dbContext.SaveChanges();
                    return new ServiceResult();
                }
                catch (Exception ex)
                {
                    Logger.ErrorToTag(Library.LogTag, string.Format("CheckOutPackagePurchaseBill error,ex:{0}", ex));
                    return new ServiceResult(1, ex.Message);
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="billId"></param>
        /// <param name="checkOutData"></param>
        /// <param name="payRecordArray"></param>
        /// <returns></returns>
        public ServiceResult CheckOutSettlementBill(Guid billId, Data.CheckOutData checkOutData, Entity.EPayRecord[] payRecordArray)
        {
            using (ASMSDbContext dbContext = new ASMSDbContext())
            {
                DateTime now = DateTime.Now;

                Entity.ESettlementBill bill = dbContext.Set<Entity.ESettlementBill>().SingleOrDefault(p => p.Id == billId && p.Status == Constant.CommonBillStatus.Enabled);
                
                if (bill == null)
                {
                    return new ServiceResult(1, "bill is not exist!");
                }

                Entity.EMaintenanceBill maintenanceBill = dbContext.Set<Entity.EMaintenanceBill>().SingleOrDefault(p => p.Id == bill.MaintenanceBillId);
                if (maintenanceBill == null)
                {
                    return new ServiceResult(1, "maintenanceBill not exist!");
                }

                // 实际支付金额
                decimal payAmount = 0;
                for (int index = 0; index < payRecordArray.Length; index++)
                {
                    payRecordArray[index].Id = Guid.NewGuid();
                    payRecordArray[index].BillId = billId;
                    payRecordArray[index].BillType = Constant.BillTypes.SettlementBill;
                    payRecordArray[index].CreatedTime = now;
                    payRecordArray[index].Creator = Sunboxsoft.ASMS.WebUtility.CookieUtility.GetUserIdString();
                    payRecordArray[index].SortIndex = index;
                    payAmount += payRecordArray[index].PayAmount;
                    dbContext.Set<Entity.EPayRecord>().Add(payRecordArray[index]);
                }

                bill.PaidAmount = payAmount;
                bill.PaidTime = now;
                if (checkOutData != null)
                {
                    if (string.IsNullOrEmpty(checkOutData.InvoiceType) == false)
                    {
                        bill.InvoiceType = checkOutData.InvoiceType;
                        bill.InvoiceNumber = checkOutData.InvoiceNumber;
                    }
                    bill.CheckOutMemo = checkOutData.Memo;
                }
                bill.Status = Constant.CommonBillStatus.Finished;
                bill.Cashier = Sunboxsoft.ASMS.WebUtility.CookieUtility.GetUserIdString();
                dbContext.Entry<Entity.ESettlementBill>(bill).State = System.Data.Entity.EntityState.Modified;

                maintenanceBill.Status = Constant.MaintenanceBillStatus.WaitDelivery;
                dbContext.Entry<Entity.EMaintenanceBill>(maintenanceBill).State = System.Data.Entity.EntityState.Modified;

                #region 创建资金入账记录
                InlineCreateService.CreateCapitalIncreaseRecord(dbContext, now, WebUtility.CookieUtility.GetUserIdString(),
                    bill.BusinessId,
                    bill.StationId,
                    Constant.CapitalChangedType.IncreaseCheckoutMaintenanceBill,
                    Constant.CapitalRoleTypes.Customer,
                    bill.CustomerId.ToString(),
                    payAmount,
                    bill.Id,
                    Constant.BillTypes.SettlementBill,
                    bill.Number);
                #endregion
                try
                {
                    dbContext.SaveChanges();
                    return new ServiceResult();
                }
                catch (Exception ex)
                {
                    Logger.ErrorToTag(Library.LogTag, string.Format("CheckOutSettlementBill error,ex:{0}", ex));
                    return new ServiceResult(1, ex.Message);
                }
            }
        }

        public ServiceResult CheckOutRechargeBill(Guid billId, Data.CheckOutData checkOutData, Entity.EPayRecord[] payRecordArray)
        {
            using (ASMSDbContext dbContext = new ASMSDbContext())
            {
                DateTime now = DateTime.Now;

                Entity.ERechargeBill bill = dbContext.Set<Entity.ERechargeBill>().SingleOrDefault(p => p.Id == billId && p.Status == Constant.CommonBillStatus.Enabled);

                if (bill == null)
                {
                    return new ServiceResult(1, "bill is not exist!");
                }

                if(bill.RechargeChannel == Constant.RechargeChannels.RechargeItem)
                {
                    if(bill.RechargeItemId == null)
                    {
                        return new ServiceResult(1, "无效的充值项!");
                    }

                    Entity.ERechargeItem rechargeItem = dbContext.Set<Entity.ERechargeItem>().SingleOrDefault(p=>p.Id == bill.RechargeItemId.Value);

                    if(rechargeItem == null)
                    {
                        return new ServiceResult(1, "无效的充值项!");
                    }
                    bill.Amount = rechargeItem.Amount;
                }
                else
                {
                    return new ServiceResult(1, "bill is not exist!");
                }

                // 实际支付金额
                decimal payAmount = 0;
                for (int index = 0; index < payRecordArray.Length; index++)
                {
                    payRecordArray[index].Id = Guid.NewGuid();
                    payRecordArray[index].BillId = billId;
                    payRecordArray[index].BillType = Constant.BillTypes.RechargeBill;
                    payRecordArray[index].CreatedTime = now;
                    payRecordArray[index].Creator = Sunboxsoft.ASMS.WebUtility.CookieUtility.GetUserIdString();
                    payRecordArray[index].SortIndex = index;
                    payAmount += payRecordArray[index].PayAmount;
                    dbContext.Set<Entity.EPayRecord>().Add(payRecordArray[index]);
                }

                bill.PaidAmount = payAmount;
                bill.PaidTime = now;
                if (checkOutData != null)
                {
                    if (string.IsNullOrEmpty(checkOutData.InvoiceType) == false)
                    {
                        bill.InvoiceType = checkOutData.InvoiceType;
                        bill.InvoiceNumber = checkOutData.InvoiceNumber;
                    }
                    bill.CheckOutMemo = checkOutData.Memo;
                }
               
                bill.Status = Constant.CommonBillStatus.Finished;
                bill.Cashier = Sunboxsoft.ASMS.WebUtility.CookieUtility.GetUserIdString();
                dbContext.Entry<Entity.ERechargeBill>(bill).State = System.Data.Entity.EntityState.Modified;

                // 更新客户余额
                Entity.EAsset balanceAsset = dbContext.Set<Entity.EAsset>().SingleOrDefault(p => p.CustomerId == bill.CustomerId 
                    && p.Type == Constant.AssetType.Balance);
                if (balanceAsset == null)
                {
                    balanceAsset = new Entity.EAsset();
                    balanceAsset.Id = Guid.NewGuid();
                    balanceAsset.CustomerId = bill.CustomerId;
                    balanceAsset.Type = Constant.AssetType.Balance;
                    balanceAsset.Value = bill.Amount;
                    dbContext.Set<Entity.EAsset>().Add(balanceAsset);
                }
                else
                {
                    balanceAsset.Value += bill.Amount;
                    dbContext.Entry<Entity.EAsset>(balanceAsset).State = System.Data.Entity.EntityState.Modified;
                }

                #region 创建资金入账记录
                InlineCreateService.CreateCapitalIncreaseRecord(dbContext, now, WebUtility.CookieUtility.GetUserIdString(),
                    bill.BusinessId.Value,
                    bill.StationId.Value,
                    Constant.CapitalChangedType.IncreaseCheckoutRechargeBill,
                    Constant.CapitalRoleTypes.Customer,
                    bill.CustomerId.ToString(),
                    payAmount,
                    bill.Id,
                    Constant.BillTypes.RechargeBill,
                    bill.Number);
                #endregion

                try
                {
                    dbContext.SaveChanges();
                    return new ServiceResult();
                }
                catch (Exception ex)
                {
                    Logger.ErrorToTag(Library.LogTag, string.Format("CheckOutRechargeBill error,ex:{0}", ex));
                    return new ServiceResult(1, ex.Message);
                }
            }
        }
    }
}
